#include "Node.h"
#include "blowfish.h"

#include <iostream>
#include <string>


using namespace std;

void initKDC() {



    // listen until a request is made
    // then prompt for Ks, Ka, Kb, and send them back to the initializer


    // prompt key A
    Blowfish keyA = Blowfish();
    keyA.Set_Passwd(NULL);

    // prompt key B

    Blowfish keyB = Blowfish();
    keyB.Set_Passwd(NULL);

    // prompt key S

    Blowfish keyS = Blowfish();
    keyS.Set_Passwd(NULL);

    // send E-Ka(
}

void initIni() {
    // my node
    Node me = Node(false);
    struct sockaddr_in kdc;
    kdc.sin_family = AF_INET;
    kdc.sin_port = htons(31337); // chosen port for listeners
    memset(&(kdc.sin_zero), '\0', 8);

    cout << "Enter the KDC that you wish to connect to: (clark/andy/shiva/j)" << endl;

  string kdcIP = "";
  bool goodInput;

  while (!goodInput) {

    getline(cin, kdcIP);

    if (kdcIP.compare("clark") == 0) {
      goodInput = true;
      kdc.sin_addr.s_addr = inet_addr("137.28.8.160");
      

    } else if (kdcIP.compare("andy") == 0) {
      goodInput = true;
      kdc.sin_addr.s_addr = inet_addr("137.28.8.161");
      

    } else if (kdcIP.compare("shiva") == 0) {
      goodInput = true;
      kdc.sin_addr.s_addr = inet_addr("137.28.8.143");
      


    } else if (kdcIP.compare("j")==0) {
        goodInput = true;
        kdc.sin_addr.s_addr = inet_addr("192.168.1.4");
    } else {

      cout << "Invalid input." << endl;

    }


  }
  char key[32];
  cout << "Enter an encryption key (up to 32 chars):" << endl;
  
  cin.get(key, 32);

  char* kdcC = (char* )kdcIP.c_str();
    // prompt key A
    Blowfish keyA = Blowfish();
    keyA.Set_Passwd(key);

    
    // prompt nonce
    cout << "Enter a nonce (up to 32 chars):" << endl;
    char nonce[32];
    cin.get(nonce, 31);

    //char* data = "req "+nonce;
    // connect to KDC
    
    
    
    if (me.conn(&kdc) == -1) {
        exit(-1);
    }

    if (me.sendMsg("hullo thar", 's') == -1) {
        exit(-1);
    }

    while (1){
        
    }

    // send request and nonce
    char msg[1024];
    // receive E-Ka(Ks, nonce, E-Kb(Ks, IDa))

    // decrypt
    keyA.Decrypt(msg, 1024);
    // validate nonce

    // obtain session key
    Blowfish keyS = Blowfish();
    keyS.Set_Passwd("");

    // close server connection fd

    

    // send to receiver E-Kb(Ks, IDa)
    struct sockaddr_in rec;
    if (me.conn(&rec) == -1) {
        exit(-1);
    }

    // receive E-Ks(second nonce)

    // send back f(second nonce)


    /* TODO: prompt number of primes to seive */

    // send sieve data to receiver

}

void initRec() {
    Node me = Node(true);
    struct sockaddr_in client;
    

    if (me.acc(&client) == -1) {
        exit(-1);
    }
    int maxSize = 150;
    char msg[150];
    if (me.receive(msg, 150, 'n') == -1) {
        exit(-1);
    } else {
        cout << "Recieved msg: " <<  msg << endl;
    }

    // wait for encoded data from the client E-Kb(Ks, IDa)

    // send back E-Ks(n2)

    // receive E-Ks(f(n2))

    // validate

    // listen for sieve data


}

int main() {

    bool goodInput = false;

    cout << "Enter your role ('k'=kdc, 'i'=initiator, 'r'=receiver)" << endl;

    string input = "";
    while (!goodInput) {
        getline(cin, input);
        goodInput = true;
        if (input.compare("k")==0) {
            initKDC();
        } else if (input.compare("i")==0) {
            initIni();
        } else if (input.compare("r") == 0) {
            initRec();
        } else {
            goodInput = false;
            cout << "Invalid input" << endl;
        }
    }


  

  
  
  

    return 0;
}


